package org.wisteria.framework.web;

import org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.text.MessageFormat;

/**
 * 统一异常处理类
 * @author Lei.Liu
 */
@Configuration
@ControllerAdvice
public class ControllerExceptionHandler {
    
    private Logger logger = LoggerFactory.getLogger(ControllerExceptionHandler.class);

    @ConditionalOnMissingBean
    @Bean
    public ExceptionMessage exceptionMessage() {
        return new ErrorTable();
    }

    @Autowired
    private ExceptionMessage exceptionMessage;
    
    @ExceptionHandler(value = BusinessException.class)
    @ResponseStatus(code = HttpStatus.OK)
    @ResponseBody
    public APIResult<Object> runtimeExceptionHandler(Exception e) {
        BusinessException businessException = null;
        String errorCode = APIResult.statusCode.fail.toString();
        String message = e.getMessage();

        if (e instanceof BusinessException) {
            businessException = (BusinessException) e;

            errorCode = businessException.errorCode;
            String[] errorMessageArgs = businessException.getErrorMessageArgs();
            if (StringUtils.hasText(errorCode)) {
                message = exceptionMessage.convertCode2Msg(errorCode);
                if (StringUtils.hasText(message) && !ArrayUtils.isEmpty(errorMessageArgs)) {
                    message = MessageFormat.format(message, errorMessageArgs);
                }
            }
        }

        logger.error(message, e);
        return APIResult.fail(errorCode, message);
    }
    
}
